package com.ai.service.made.impl;


import com.ai.common.constant.*;
import com.ai.common.CommonResponse;
import com.ai.common.constant.enumP.FunctionTypeEnums;
import com.ai.common.constant.enumP.IndustryAlarmIdEnums;
import com.ai.common.constant.enumP.IndustryAlarmLevelEnums;
import com.ai.entity.BasePage;
import com.ai.entity.Industry.IndustryAlarmMessage;
import com.ai.entity.alarm.*;


import com.ai.entity.function.FunctionPO;
import com.ai.entity.made.DeleteSpecifiedRangeParam;
import com.ai.entity.made.RegionBase;
import com.ai.entity.made.camera.CameraPO;
import com.ai.entity.network.IdentifySysToL1Message;
import com.ai.entity.server.ServerPO;
import com.ai.mapper.alarm.RecordAlarmMapper;
import com.ai.model.made.RegionalViolationDto;
import com.ai.model.made.TopFiveViolationsDto;
import com.ai.model.param.AlarmToRocketMQParam;
import com.ai.model.param.AlgorithmAlarmParam;
import com.ai.model.vo.ActualRecordVo;
import com.ai.model.vo.EachMouthRecordCount;
import com.ai.model.vo.LatestThreeYearRecordCount;
import com.ai.networking.websocket.service.WebSocket;
import com.ai.networking.websocket.service.entity.WSMessage;
import com.ai.service.made.*;
import com.ai.service.rocketMq.RocketMQProducerService;
import com.ai.util.GetCameraPlaybackUrlUtil;
import com.ai.util.HttpRequestUtil;
import com.ai.util.SecurityUtils;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import im.qingtui.qbee.open.platfrom.msg.model.param.msg.Attachment;
import im.qingtui.qbee.open.platfrom.msg.model.param.msg.SendAlarmMsgParam;
import im.qingtui.qbee.open.platfrom.msg.service.MsgService;
import lombok.extern.slf4j.Slf4j;

//import org.checkerframework.checker.units.qual.A;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeParseException;
import java.time.temporal.ChronoUnit;
import java.util.*;
import java.util.concurrent.CopyOnWriteArraySet;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;

import static com.ai.networking.netty.client.BootNettyClientChannelCache.clientSendMessage;

/**
 * <p>
 * 服务实现类
 *
 * </p>
 *
 * @author Mr.Chen
 * @since 2020-06-19
 */
@Service
@Slf4j
public class RecordAlarmServiceImpl extends ServiceImpl<RecordAlarmMapper, RecordAlarmPO> implements RecordAlarmService {


    @Resource
    IRegionManageService iRegionManageService;

    @Resource
    IRegionBaseService iRegionBaseService;

    @Resource
    RecordAlarmMapper recordAlarmMapper;
    @Resource
    CameraService cameraService;
    @Resource
    FunctionService functionService;

    @Resource
    L2SignalService l2SignalService;

    @Autowired
    private  ServerService serverService;

//    @Resource
//    private MsgService msgService;

    @Autowired
    private RocketMQProducerService rocketMQProducerService;

    @Autowired
    private ISignalRecordService iSignalRecordService;


    @Autowired
    private IDelAlarmLogService iDelAlarmLogService;



    private static volatile AtomicInteger FREQUENCY_A3_NUM= new AtomicInteger(0);

    @Value("${api.ai.delPath}")
    private String snapPhotoDir;


    @Resource
    private IQbeeTemplateConfigurationService iQbeeTemplateConfigurationService;

    @Resource
    private IQbeeTemplateService iQbeeTemplateService;



//    public static volatile Boolean NOTIFICATIONS_A3 = false;//a3移板机
//
//    public static volatile Boolean TRACK_STACKING = false;//叠钢
//
//    public static volatile Boolean STEEL_INSTALLATION_DEVIATION = false;//装钢偏斜
//    public static volatile Boolean STEEL_DRAWING_DEVIATION = false;//抽钢偏斜
//    public static volatile Boolean FURNACE_DOOR_STATUS =false;//炉门状态
//    public static volatile Boolean RANGING_STEEL = false;//钢板测距
    /**

     *

     * }
     */

    /**
     * 算法提交识别警告
     *
     * @param alarmBOList
     * @return
     */
    @Override
    public CommonResponse addAlarm(List<AlgorithmAlarmBO> alarmBOList) {
        for (AlgorithmAlarmBO algorithmAlarmBO : alarmBOList) {

            if (algorithmAlarmBO.getCameraId() == null || algorithmAlarmBO.getCameraId() == 0) {
                return CommonResponse.error("没有摄像头ID");
            }

            if (StringUtils.isEmpty(algorithmAlarmBO.getSnapPhoto())) {
                return CommonResponse.error("没有抓拍图片");
            }

            if (StringUtils.isEmpty(algorithmAlarmBO.getFunctionType()) ) {
                return CommonResponse.error("没有警报类型");
            }

            CameraPO cameraPO = cameraService.getById(algorithmAlarmBO.getCameraId());

            if (cameraPO == null) {
                return CommonResponse.error("摄像头不存在");
            }

            SimpleDateFormat sformat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");//格式
            Date date = new Date();
            try {
                if (!StringUtils.isEmpty(algorithmAlarmBO.getCreateTime())) {
                    date = sformat.parse(algorithmAlarmBO.getCreateTime());
                }
            } catch (ParseException e) {
            }

            //算法提交的图片为路径
            String webPhotoPath = algorithmAlarmBO.getSnapPhoto();
            String webVideoPath = algorithmAlarmBO.getSnapVideo();


            //处理识别图片
//            if (!algorithmAlarmBO.getSnapPhoto().isEmpty()) {
//
//                if (algorithmAlarmBO.getSnapPhotoStatus() == 2) {//base64，转存到本地，然后传入路径
//                  String snapPhoto = Base64Util.GenerateFile("/images/",algorithmAlarmBO.getSnapPhoto(),
//                          "jpg",cameraPO.getCode(),Integer.parseInt(algorithmAlarmBO.getFunctionType()),algorithmAlarmBO.getResult() );
//                    webPhotoPath=snapPhoto;
//                }else {
//                    webPhotoPath=algorithmAlarmBO.getSnapPhoto();
//                }
//
//                String photo = algorithmAlarmBO.getSnapPhoto();
//                if (photo.indexOf("http://") != -1) {
//                    webPhotoPath = photo;
//                } else {
//                    webPhotoPath = Base64Util.GenerateFile("/images/", photo, "jpg", cameraPO.getCode(), algorithmAlarmBO.getType(), algorithmAlarmBO.getState());
//                }
//            }
            //处理识别视频,先默认为路径
//            if (algorithmAlarmBO.getSnapVideoStatus() != null && algorithmAlarmBO.getSnapVideoStatus() != 0 && algorithmAlarmBO.getSnapVideoStatus() .equals(2) ) {
//
//                if (!StringUtils.isEmpty(algorithmAlarmBO.getSnapVideo())) {
//                    String snapVideo = Base64Util.GenerateFile("/videos/",algorithmAlarmBO.getSnapVideo(), "snapVideo/", "jpg");
//                    algorithmAlarmBO.setSnapVideo(snapVideo);
//                }
//            }
//            if (!algorithmAlarmBO.getSnapVideo().isEmpty())
//                webVideoPath = Base64Util.GenerateFile("/videos/", algorithmAlarmBO.getSnapVideo(), "mp4", cameraPO.getCode(), algorithmAlarmBO.getType(), algorithmAlarmBO.getState());

//            int status = algorithmAlarmBO.getResult();
            Integer type = Integer.parseInt(algorithmAlarmBO.getFunctionType());

            //保存违规对象
            RecordAlarmPO alarmPO = new RecordAlarmPO();
            alarmPO.setSnapVideo(algorithmAlarmBO.getSnapVideo());//视频路径
            alarmPO.setCameraId(algorithmAlarmBO.getCameraId());
            alarmPO.setCameraCode(cameraPO.getCode());

            alarmPO.setFunctionType(type);
            alarmPO.setSnapPhoto(webPhotoPath);
            alarmPO.setSnapVideo(webVideoPath);
            alarmPO.setSubgroup(type);
            alarmPO.setCreateTime(date);
            alarmPO.setUpdateTime(date);


            save(alarmPO);

            //调用mq将告警信息发送给第三方平台
            AlarmToRocketMQParam rocketMQParam = new AlarmToRocketMQParam();
            rocketMQParam.setFunctionType(alarmPO.getFunctionType());
            rocketMQParam.setCameraIndexCode(alarmPO.getCameraCode());
            rocketMQParam.setCameraIp(cameraPO.getIp());
            rocketMQParam.setSnapVideo(alarmPO.getSnapVideo());
            rocketMQParam.setSnapPhoto(alarmPO.getSnapPhoto());
            rocketMQParam.setCreateTime(sformat.format(date));

            try {
                rocketMQProducerService.asyncSendMsg(JSONObject.toJSONString(rocketMQParam),
                        String.valueOf(alarmPO.getFunctionType()),
                        String.valueOf(alarmPO.getId()));
            }catch (Exception e){
                log.error("===========================  mq发送异常  ===========================");
                log.error(e.getMessage());
                log.error("消息投递异常",e);
            }

            //先发送到自定义的配置模板上
            customSendAlarmMsgToIndustry(alarmPO,cameraPO);

            /**
             * 使用上述的自定义模板，废弃原有方式
             */
            // : 2024-03-18 将告警推送给互联网工业大平台
//            sendAlarmMsgToIndustry(alarmPO,cameraPO);



            sendWebSocket(type);
            algorithmAlarmBO.setSnapPhoto(webPhotoPath);
            algorithmAlarmBO.setSnapVideo(webVideoPath);
        }


        return CommonResponse.ok("警告发送成功");
    }


    @Override
//    @Transactional
    public CommonResponse addWarningRecord(AlgorithmAlarmParam algorithmAlarmParams) {

        List<String> alarmParamsTypes = algorithmAlarmParams.getTypes();
        ArrayList<AlgorithmAlarmBO> alarmBOArrayList = new ArrayList<>();
        if (!CollectionUtils.isEmpty(alarmParamsTypes)){
            for (String type : alarmParamsTypes) {
                AlgorithmAlarmBO algorithmAlarmBO = new AlgorithmAlarmBO();
                //摄像头id
                algorithmAlarmBO.setCameraId(algorithmAlarmParams.getCameraId());
                //功能类型
                algorithmAlarmBO.setFunctionType(type);
                //识别时间
                algorithmAlarmBO.setCreateTime(algorithmAlarmParams.getCreateTime());
                //抓怕图片
                algorithmAlarmBO.setSnapPhoto(algorithmAlarmParams.getSnapPhoto());
                //抓拍视频路径
                algorithmAlarmBO.setSnapVideo(algorithmAlarmParams.getSnapVideo());
                alarmBOArrayList.add(algorithmAlarmBO);
            }

            return this.addAlarm(alarmBOArrayList);
        }


        return CommonResponse.error("未携带警告类型");
    }

    /**
     * 向plc发送消息
     * @param signalRecord
     * @param algorithmAlarmBO
     */
    private void sendMsgToPlc(SignalRecord signalRecord, AlgorithmAlarmBO algorithmAlarmBO,String plcCode) {

        String nettyCode = signalRecord.getNettyCode();
        Integer telID = getTelIDByFunType(Integer.parseInt(algorithmAlarmBO.getFunctionType()), signalRecord.getSignalResource());

        IdentifySysToL1Message identifySysToL1Message = new IdentifySysToL1Message();
        identifySysToL1Message.setTelID(telID);//电文号
        identifySysToL1Message.setPlanNo(algorithmAlarmBO.getStripNo());//版批号
        identifySysToL1Message.setDoorNum(algorithmAlarmBO.getDoorNum());//炉门编号
        identifySysToL1Message.setResult(algorithmAlarmBO.getResult());// 1 正常 2 异常
//        identifySysToL1Message.setSpare();
        String jsonString = JSONObject.toJSONString(identifySysToL1Message);
        int length = jsonString.getBytes().length;

        //填充真实数据的字节长度
        identifySysToL1Message.setTelLen(length);

        String msgJSON = JSONObject.toJSONString(identifySysToL1Message);

        clientSendMessage(plcCode,msgJSON);

    }

    public static Integer getTelIDByFunType(Integer funType ,String clientIp){

        Integer telID = 0;

        if (funType.equals(FunctionTypeConstants.A3_TRANSFER_SLAB_DEVIATION)){
            telID= AlgorithmConstant.A3_TRANSFER_MACHINE_AUTOMATIC_CONFIRMATION;
        } else if (funType.equals(FunctionTypeConstants.SUPERPOSE_STEEL_IDENTIFICATION)) {
            //一个信号开启了两个功能，  那么收到某一个功能的信号识别记录是否需要通知plc
            telID=AlgorithmConstant.TRACK_STACKING_STEEL;

        } else if (funType.equals(FunctionTypeConstants.RANGING_STEEL)) {
            telID=AlgorithmConstant.TRACK_STACKING_STEEL;

        } else if (funType.equals(FunctionTypeConstants.LOAD_STEEL_DEVIATION) && clientIp.equals(PlcConstants.PLC_2_IP)) {
            telID=AlgorithmConstant.STEEL_INSTALLATION_DEVIATION_30_4;

        } else if (funType.equals(FunctionTypeConstants.TAKE_STEEL_DEVIATION) && clientIp.equals(PlcConstants.PLC_2_IP)) {
            telID=AlgorithmConstant.STEEL_DRAWING_DEVIATION_30_4;

        } else if (funType.equals(FunctionTypeConstants.STOVE_STATUS) && clientIp.equals(PlcConstants.PLC_2_IP)) {
            telID=AlgorithmConstant.FURNACE_DOOR_STATUS_30_4;

        }else if (funType.equals(FunctionTypeConstants.LOAD_STEEL_DEVIATION) && clientIp.equals(PlcConstants.PLC_3_IP)) {
            telID=AlgorithmConstant.STEEL_INSTALLATION_DEVIATION_30_5;

        } else if (funType.equals(FunctionTypeConstants.TAKE_STEEL_DEVIATION) && clientIp.equals(PlcConstants.PLC_3_IP)) {
            telID=AlgorithmConstant.STEEL_DRAWING_DEVIATION_30_5;

        } else if (funType.equals(FunctionTypeConstants.STOVE_STATUS) && clientIp.equals(PlcConstants.PLC_3_IP)) {
            telID=AlgorithmConstant.FURNACE_DOOR_STATUS_30_5;

        }
        return telID;
    }


    private void sendWebSocket(int type) {
        WSMessage wsMessage = new WSMessage();
        wsMessage.setContent("UPDATE");

        if (CommonArgs.WS_RECORD_MAP.containsKey(type)
                && CommonArgs.WS_RECORD_MAP.get(type) != null
                && CommonArgs.WS_RECORD_MAP.get(type).size() > 0) {
            CopyOnWriteArraySet<WebSocket> webSockets = CommonArgs.WS_RECORD_MAP.get(type);
            for (WebSocket ws : webSockets) {
                ws.sendMessage(wsMessage);
            }
        }
    }

    private void sendHttp(RecordAlarmPO alarmPO) {


    }


    /**
     * 分页查询
     *
     * @param page
     * @return
     */
    @Override
    public CommonResponse selectByPage(RecordAlarmPage page) {

        IPage<RecordAlarmVO> voIPage = new BasePage<>();
        HashMap<String,String> cameraRegionMap = new HashMap<>();
        RegionBase regionBase = null;

        if (!org.apache.commons.lang3.StringUtils.isBlank(page.getRegionId())){
            CommonResponse serviceBindListRes = iRegionManageService.getBindList(page.getRegionId());
            ArrayList<String> regionManageCameraCode = (ArrayList<String>) serviceBindListRes.getData();
            regionBase = iRegionBaseService.getById(page.getRegionId());
            page.setCameraCodes(regionManageCameraCode);
        }else {
            //获取当前用户管理的摄像头
            cameraRegionMap = SecurityUtils.getRegionManageCamerasCode(iRegionBaseService, iRegionManageService);
            if (CollectionUtils.isEmpty(cameraRegionMap)){
                //当前区域没有管理任何摄像头
                return CommonResponse.ok(voIPage);
            }
            //获取所有摄像头code
            ArrayList<String> cameraCodes = new ArrayList<>(cameraRegionMap.keySet());
            page.setCameraCodes(cameraCodes);
        }

        QueryWrapper<RecordAlarmPO> queryWrapper = new QueryWrapper<>();
        queryWrapper.orderByDesc("create_time");
        queryWrapper = page.getQuery(queryWrapper);
        voIPage = recordAlarmMapper.getRecordListQuickly(page, queryWrapper);
        List<RecordAlarmVO> records = voIPage.getRecords();



        for (RecordAlarmVO record : records) {
            if (record.getIsError()==9) {
                break;
            }
            String name = functionService.getNameByCode(record.getFunctionType());
            CameraPO cameraPO = cameraService.getById(record.getCameraId());

            //填充区域名称
            if (org.apache.commons.lang3.StringUtils.isBlank(page.getRegionId())
                    ){
                String regionCode = cameraRegionMap.get(cameraPO.getCode());
                RegionBase regionBaseByCode = iRegionBaseService.getRegionBaseByCode(regionCode);
                //区域名
                record.setRegionName(regionBaseByCode.getRegionName());
            } else if ((RegionConstants.ALL_REGION_ID.equals(page.getRegionId()))) {
                //查询全部区域---填充各个告警的区域信息
                record.setRegionName(iRegionManageService.getRegionByCameraId(cameraPO.getId()));
            } else {
                record.setRegionName(regionBase.getRegionName());
            }

            record.setFunctionNickname(name);
            record.setCameraNickname(cameraPO == null ? "" : cameraPO.getNickname());
        }
        voIPage.setRecords(records);
        return CommonResponse.ok(voIPage);
    }

    /**
     * 是否误报
     *
     * @param recordAlarmBO
     * @return
     */
    @Override
    public CommonResponse signError(RecordAlarmBO recordAlarmBO) {
        RecordAlarmBO alarmBO = new RecordAlarmBO();
        alarmBO.setId(recordAlarmBO.getId());
        alarmBO.setIsError(recordAlarmBO.getIsError());
        alarmBO.setReviewComments(recordAlarmBO.getReviewComments());
        RecordAlarmPO recordAlarmPO = RecordAlarmBO.convertBOToPO(alarmBO);
        if (updateById(recordAlarmPO)) {
            return CommonResponse.ok("标记成功");
        }
        return CommonResponse.error("标记失败");
    }

    @Override
    public List<RecordAlarmPO> getRecordByCameraCodeAndFunType(ArrayList<String> cameraCode, String funType) {

        List<RecordAlarmPO> recordAlarmPOList =  recordAlarmMapper.getRecordByCameraCodeAndFunType(cameraCode,funType);

        return recordAlarmPOList;
    }

    @Override
    public List<TopFiveViolationsDto> topFiveViolations() {

        List<TopFiveViolationsDto> topFiveViolationsDtos= this.baseMapper.topFiveViolations();

        return topFiveViolationsDtos;
    }

    @Override
    public List<RegionalViolationDto> regionalViolation() {

        List<RegionalViolationDto> regionalViolationDtoList = this.baseMapper.regionalViolation();

        return regionalViolationDtoList;
    }

    @Override
    public CommonResponse latestRecord() {
        // 获取当前日期
        LocalDate today = LocalDate.now();
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        String date = today.format(formatter);

        QueryWrapper<RecordAlarmPO> queryWrapper = new QueryWrapper<>();
        //只获取当天的最新十条
        queryWrapper.ge("create_time",date);
        queryWrapper.orderByDesc("create_time");
        queryWrapper.last("limit 10");
        List<RecordAlarmPO> latestRecordList = this.list(queryWrapper);
        // DATE格式化
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        ArrayList<ActualRecordVo> recordVoArrayList = new ArrayList<>();

        if (!CollectionUtils.isEmpty(latestRecordList)){
            for (RecordAlarmPO recordAlarmPO : latestRecordList) {
                //组装实时违规记录字段
                ActualRecordVo actualRecordVo = new ActualRecordVo();

                CameraPO cameraPO = cameraService.getById(recordAlarmPO.getCameraId());

                if (null != cameraPO){
                    actualRecordVo.setCameraName(cameraPO.getNickname());
                    actualRecordVo.setCameraCode(cameraPO.getCode());
                }

                FunctionPO functionPO= functionService.getFunByType(recordAlarmPO.getFunctionType());
                if (null != functionPO){
                    actualRecordVo.setFunName(functionPO.getNickname());
                }
                RegionBase regionBase = iRegionBaseService.getRegionByCameraId(cameraPO.getId());
                if (null != regionBase){
                    actualRecordVo.setRegionName(regionBase.getRegionName());
                }

                actualRecordVo.setViolationTime(simpleDateFormat.format(recordAlarmPO.getCreateTime()));

                //违规图片
                actualRecordVo.setActualPhoto(recordAlarmPO.getSnapPhoto());

                recordVoArrayList.add(actualRecordVo);
            }
        }

        return CommonResponse.ok(recordVoArrayList);
    }

    @Override
    public CommonResponse getCameraPlaybackUrl(String recordId) {

        /**
         * 根据告警记录id，查找对应的摄像头
         */
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        RecordAlarmPO recordAlarmPO = this.getById(recordId);

        String serverIp = this.getServerIpByRecord(recordId);

        String previewUrl = GetCameraPlaybackUrlUtil.getCameraPlaybackUrl(recordAlarmPO.getCameraCode(),simpleDateFormat.format(recordAlarmPO.getCreateTime()));
        //算法直播服务解析不了& ，替换为AND字符
        String replaceUrl = previewUrl.replace("&", "AND");
        HashMap<String, Object> res = new HashMap<>(16);
        res.put("url",replaceUrl);
        res.put("serverIp",serverIp);
        return CommonResponse.ok(res);

    }

    @Override
    public CommonResponse deleteSpecifiedRange(DeleteSpecifiedRangeParam deleteSpecifiedRangeParam) {

        //校验参数，判断删除的数据距离现在是否一年时间
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        try {
            // 将字符串解析为 LocalDate 对象
            LocalDate beginDate = LocalDate.parse(deleteSpecifiedRangeParam.getDatebegin(), formatter);
            LocalDate endDate = LocalDate.parse(deleteSpecifiedRangeParam.getDateend(), formatter);

            // 获取当前时间的 LocalDate 对象
            LocalDate currentDate = LocalDate.now();

            // 计算一年的天数阈值
            long daysInAYear = ChronoUnit.DAYS.between(currentDate.minusYears(1), currentDate);

            // 计算开始日期与当前日期的天数差距
            long daysFromBegin = ChronoUnit.DAYS.between(beginDate, currentDate);

            // 计算截止日期与当前日期的天数差距
            long daysFromEnd = ChronoUnit.DAYS.between(endDate, currentDate);

            // 判断是否超过一年的时间范围
            if (!(daysFromEnd > daysInAYear || daysFromBegin > daysInAYear)  ) {
              return CommonResponse.error("一年之内的数据不允许删除");
            }

        } catch (DateTimeParseException e) {
            log.error("===========================  日期格式不正确  ===========================",e);
            return CommonResponse.error("日期格式不正确");
        }

        /**
         * 调用算法接口
         *      删除成功 200 ------ 删除区间内所有数据
         *              500 ------ 剔除删除失败的时间区间
         *                  删除之前先统计各区间总共有多少数据---按月删除
         */
        //交由算法进行删除图片


        //获取所有的服务器ip
        List<ServerPO> serverPOS = serverService.list();

        //调用算法，删除图片
        for (ServerPO serverPO : serverPOS) {
            try {
                //开始轮询调用各服务器删除接口
                String alarmServerQuestUrl = "http://";
                String param = "";
                alarmServerQuestUrl= alarmServerQuestUrl+serverPO.getIp()+":8600/dateDelete";

                log.info("=========================== 算法请求路径:{}  ===========================",alarmServerQuestUrl);

                String dateBegin = deleteSpecifiedRangeParam.getDatebegin().replace("-","");
                String dateEnd = deleteSpecifiedRangeParam.getDateend().replace("-","");
                param = "dateBegin="+dateBegin+"&dateEnd="+dateEnd+"&fileDir="+snapPhotoDir;
                log.info("=========================== 准备请求算法：{}  ===========================",param);
                String res = HttpRequestUtil.sendGet(alarmServerQuestUrl, param);

                if (StringUtils.isEmpty(res) || "null".equals(res)) {
                    throw new RuntimeException("==================== 网络请求失败！=======================");
                }

                //解析算法返回数据
                JSONObject jsonObject = JSONObject.parseObject(res);
                String alReturnJson = jsonObject.toJSONString();
                log.info("===========================  算法返回数据：{} ===========================",alReturnJson);
                int resultCode = Integer.parseInt(jsonObject.getString("code"));
                if (resultCode == 200){
                    //需要全部清除---不在delFailDateMap，中追加需要跳过的数据
                    iDelAlarmLogService.saveSuccDelLog(deleteSpecifiedRangeParam,1, String.valueOf(serverPO.getId()));
                }else if (resultCode == 500){
                    //删除失败的日期时间
                    List<String>  delFailList = (List<String>) jsonObject.get("data");
                    iDelAlarmLogService.savepartAbnormalDelLog(deleteSpecifiedRangeParam,2,delFailList,String.valueOf(serverPO.getId()));
                }else {
                    //全部删除失败，该服务器相关的数据全部不执行删除操作
                    iDelAlarmLogService.saveAllAbnormalDelLog(deleteSpecifiedRangeParam,3,String.valueOf(serverPO.getId()));
                }
            }catch (Exception e){
                log.warn(e.getMessage());
                //记录网络请求失败的服务器
                iDelAlarmLogService.saveAllAbnormalDelLog(deleteSpecifiedRangeParam,4,String.valueOf(serverPO.getId()));
            }
        }

        return CommonResponse.ok("删除成功");

    }

    @Override
    public List<EachMouthRecordCount> getEachMouthRecordByCameraCodeAndFunType(ArrayList<String> cameraCode, String funType) {

        List<EachMouthRecordCount>  eachMouthRecordCounts =   baseMapper.getEachMouthRecordByCameraCodeAndFunType(cameraCode,funType);
        return eachMouthRecordCounts;
    }

    @Override
    public List<LatestThreeYearRecordCount> getLatestThreeYearRecordCount() {
        return baseMapper.getLatestThreeYearRecordCount();
    }

    public  Map<String,Object> deletePictureByAlarm(DeleteSpecifiedRangeParam deleteSpecifiedRangeParam){

        //交由算法进行删除图片
        String alarmServerQuestUrl = "http://";
        String param = "";
        String snapPhotoDir = "/home/apache-tomcat-9.0.78/webapps/snapPhoto";
        //获取所有的服务器ip
        List<ServerPO> serverPOS = serverService.list();
        LinkedList<String> linkedList = new LinkedList<>();
        //需要删除的数据
        HashMap<String, List<Integer>> needDelServerCameraRelationMap = new HashMap<>(16);
        //删除失败的日期
        HashMap<String, List<String>> delFailDateMap = new HashMap<>(16);
        //删除失败的数据
        HashMap<String, List<Integer>> ignoreMap = new HashMap<>(16);

        //调用算法，删除图片
        for (ServerPO serverPO : serverPOS) {
           try {
               List<CameraPO> cameraPOList =  cameraService.getBindCamera(serverPO);
               List<Integer> cameraIds = cameraPOList.stream().map(CameraPO::getServerId).collect(Collectors.toList());
               needDelServerCameraRelationMap.put(serverPO.getIp(),cameraIds);
               //开始轮询调用各服务器删除接口
               alarmServerQuestUrl= alarmServerQuestUrl+serverPO.getIp()+":8600/dateDelete";
               String dateBegin = deleteSpecifiedRangeParam.getDatebegin().replace("-","");
               String dateEnd = deleteSpecifiedRangeParam.getDateend().replace("-","");
               param = "dateBegin="+dateBegin+"&dateEnd="+dateEnd+"&fileDir="+snapPhotoDir;
               String res = HttpRequestUtil.sendGet(alarmServerQuestUrl, param);

               if (StringUtils.isEmpty(res) || "null".equals(res)) {
                   throw new RuntimeException("==================== 网络请求失败！=======================");
               }

               //解析算法返回数据
               JSONObject jsonObject = JSONObject.parseObject(res);
               String alReturnJson = jsonObject.toJSONString();
               log.info("===========================  算法返回数据：{} ===========================",alReturnJson);
               int resultCode = Integer.parseInt(jsonObject.getString("code"));
               if (resultCode == 200){
                //需要全部清除---不在delFailDateMap，中追加需要跳过的数据
               }else if (resultCode == 500){
                   //删除失败的日期时间
                   List<String>  delFailList = (List<String>) jsonObject.get("data");
                   delFailDateMap.put(serverPO.getIp(),delFailList);
               }else {
                   //全部删除失败，该服务器相关的数据全部不执行删除操作
                   needDelServerCameraRelationMap.remove(serverPO.getIp());
               }
           }catch (Exception e){
               log.warn(e.getMessage());
               //记录网络请求失败的服务器
               needDelServerCameraRelationMap.remove(serverPO.getIp());
           }
        }

        //删除db内的数据  needDelServerCameraRelationMap是所有需要删除的关系, delFailDateMap 需要跳过的日期
        //执行删除操作
        for (String serverIp : needDelServerCameraRelationMap.keySet()) {
            QueryWrapper<RecordAlarmPO> queryWrapper = new QueryWrapper<>();
            List<Integer> needDelCameraIds = needDelServerCameraRelationMap.get(serverIp);
            queryWrapper.in("camera_id",needDelCameraIds);
            queryWrapper.ge((!com.alibaba.druid.util.StringUtils.isEmpty(deleteSpecifiedRangeParam.getDatebegin())), "create_time", deleteSpecifiedRangeParam.getDatebegin())
                    .lt((!com.alibaba.druid.util.StringUtils.isEmpty(deleteSpecifiedRangeParam.getDateend())), "create_time", deleteSpecifiedRangeParam.getDateend());

            if (!CollectionUtils.isEmpty(delFailDateMap.get(serverIp))){
                queryWrapper.notIn("create_time",delFailDateMap.get(serverIp));
            }

            //删除之前需要先判断删除了多少数据
            //首先需要知道传入的时间是否在一年之间，如果不是，需要进行划分
            List<String> timeInterval = getTimeInterval(deleteSpecifiedRangeParam);
            if (timeInterval.size()==2){
                //删除的就是同一年的数据  直接统计数据，插表

            }

            this.remove(queryWrapper);
        }
        return null;
    }

    /**
     * 开始结束年区间
     * @param deleteSpecifiedRangeParam
     * @return 0 1 2 3  第一年开始 第一年结束 第二年开始 第二年结束
     */
    public List<String> getTimeInterval(DeleteSpecifiedRangeParam deleteSpecifiedRangeParam){
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
        List<String> subDataList = new ArrayList<>();
        try {
            Date dateBegin = sdf.parse(deleteSpecifiedRangeParam.getDatebegin().replace("-",""));
            Date dateEnd = sdf.parse(deleteSpecifiedRangeParam.getDateend().replace("-",""));

            // TODO: 2024-07-26 目前默认最大只有两年的区间
            if (dateBegin.getYear() != dateEnd.getYear()){
                subDataList.add(deleteSpecifiedRangeParam.getDatebegin());
                Calendar cal = Calendar.getInstance();
                cal.setTime(dateBegin);
                cal.roll(Calendar.DAY_OF_YEAR, -1);
                subDataList.add(sdf.format(cal.getTime()));

                //获取第二个日期年的第一天
                cal.setTime(dateEnd);
                cal.set(Calendar.DAY_OF_YEAR,1);
                Date firstDayOfYear = cal.getTime();
                String endYearBeginStartStr = sdf.format(firstDayOfYear);
                subDataList.add(endYearBeginStartStr);
                subDataList.add(deleteSpecifiedRangeParam.getDateend());
            }else {
                //删除的是同一年的数据
                subDataList.add(deleteSpecifiedRangeParam.getDatebegin());
                subDataList.add(deleteSpecifiedRangeParam.getDateend());
            }

        }catch (ParseException e){
            log.error("=========================== 时间格式化失败 {}  ===========================",e.getMessage());
        }
        return subDataList;
    }



    /**
     * 获取服务器ip
     * @param recordId
     * @return
     */
    private String getServerIpByRecord(String recordId) {

       return   baseMapper.getServerIpByRecord(recordId);

    }



    private  void sendAlarmMsgToIndustry(RecordAlarmPO alarmPO, CameraPO cameraPO){
        IndustryAlarmMessage message = new IndustryAlarmMessage();
        SendAlarmMsgParam param = new SendAlarmMsgParam();

        String funType = alarmPO.getFunctionType().toString();
        if (funType.equals(IndustryAlarmIdEnums.HELMET_DETECTION.getType())){
            param.setAlarmConfigId(IndustryAlarmIdEnums.HELMET_DETECTION.getValue());
        } else if (funType.equals(IndustryAlarmIdEnums.SMOCK_DETECTION.getType())) {
            param.setAlarmConfigId(IndustryAlarmIdEnums.SMOCK_DETECTION.getValue());
        } else if (funType.equals(IndustryAlarmIdEnums.SINGLE_PERSON_HOMEWORK_DETECTION.getType())) {
            param.setAlarmConfigId(IndustryAlarmIdEnums.SINGLE_PERSON_HOMEWORK_DETECTION.getValue());
        } else if (funType.equals(IndustryAlarmIdEnums.FLAME_DETECTION.getType())) {
            param.setAlarmConfigId(IndustryAlarmIdEnums.FLAME_DETECTION.getValue());
        }
        param.setLevelId(IndustryAlarmLevelEnums.THIRD_LEVEL.getValue());

        //添加附件
        Attachment attachment = new Attachment();
        // 1 图片，2视频
        attachment.setType(1);
        attachment.setLinkUrl(alarmPO.getSnapPhoto());
        LinkedList<Attachment> attachmentList = new LinkedList<>();
        attachmentList.add(attachment);
        param.setAttachmentList(attachmentList);

        //追加消息内容
        // 获取当前时间
        LocalDateTime now = LocalDateTime.now();
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");

        String regionName = iRegionManageService.getRegionByCameraId(cameraPO.getId());
        String nickname = cameraPO.getNickname();
        String formatTime = now.format(formatter);

        String content = regionName + "--"+nickname+"--"+formatTime;

        param.setContent(content);


        log.info("===========================  sendAlarmMsgToIndustry：{}  ===========================",JSONObject.toJSONString(param));
        MsgService.sendAlarmMsg(param);
        log.info("===========================  发送告警到工业大平台  ===========================");
    }

    private  void customSendAlarmMsgToIndustry(RecordAlarmPO alarmPO, CameraPO cameraPO){


        List<String>  templateConfigIds = iQbeeTemplateConfigurationService.getTemplateIdByCameraId(cameraPO.getId());

        if (!CollectionUtils.isEmpty(templateConfigIds)){
            //将告警信息推送到指定的各个模板
            for (String templateConfigId : templateConfigIds) {
                IndustryAlarmMessage message = new IndustryAlarmMessage();
                SendAlarmMsgParam param = new SendAlarmMsgParam();
                param.setAlarmConfigId(templateConfigId);

                param.setLevelId(IndustryAlarmLevelEnums.THIRD_LEVEL.getValue());

                //添加附件
                Attachment attachment = new Attachment();
                // 1 图片，2视频
                attachment.setType(1);
                attachment.setLinkUrl("http://"+alarmPO.getSnapPhoto());
                LinkedList<Attachment> attachmentList = new LinkedList<>();
                attachmentList.add(attachment);
                param.setAttachmentList(attachmentList);

                //追加消息内容
                // 获取当前时间
                LocalDateTime now = LocalDateTime.now();
                DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");

//                String regionName = iRegionManageService.getRegionByCameraId(cameraPO.getId());

                String nickname = cameraPO.getNickname();
                String formatTime = now.format(formatter);
                String functionType = FunctionTypeEnums.getFunctionNameByType(String.valueOf(alarmPO.getFunctionType()));
                //摄像头名称------告警类型-------告警时间
                String content = nickname+"------"+functionType+"------"+formatTime;

                param.setContent(content);

                log.info("===========================  customSendAlarmMsgToIndustry：{}  ===========================",JSONObject.toJSONString(param));
                MsgService.sendAlarmMsg(param);
                log.info("===========================  摄像头的告警发送到指定的模板 ：{}  ===========================",templateConfigId);
            }
        }


    }
}
